#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;

pthread_cond_t cond=PTHREAD_COND_INITIALIZER;//条件变量
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;//锁

int tickets=1000;


void* threadroutine(void* args)
{
    string name=static_cast<const char*>(args);
    while(true)
    {
        // sleep(1);
        pthread_mutex_lock(&mutex);//加锁

        if(tickets>0)
        {
            cout<<name<<", get a ticket: "<<tickets--<<endl;
            usleep(100);
        }
        else
        {
            cout<<"没票了"<<name<<endl;
            pthread_cond_wait(&cond,&mutex);//让线程满足条件变量，才被唤醒
            //1.让线程在进行等待的时候，会自定释放锁
            //2.线程被唤醒的时候，是在临界区内唤醒的，当线程被唤醒的时候，线程pthread_cond_wait返回的时候
            //要重新申请并持有锁
            //3.当线程被唤醒的时候，重新申请并持有锁的本质是也要参与锁的竞争
        }
        pthread_mutex_unlock(&mutex);
    }
}

//主线程
int main()
{
    pthread_t t1,t2,t3;
    pthread_create(&t1,nullptr,threadroutine,(void*)"thread - 1");
    pthread_create(&t2,nullptr,threadroutine,(void*)"thread - 2");
    pthread_create(&t3,nullptr,threadroutine,(void*)"thread - 3");

    sleep(5);//主线程5s之后，开始唤醒一个线程
    while(true)
    {
        // sleep(1);
        // pthread_cond_signal(&cond);

        sleep(20);//休息20s再放一批票
        pthread_mutex_lock(&mutex);
        tickets+=1000;
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond);//让一个线程被唤醒，才后这个线程在去抢票
    }


    
    pthread_join(t1,nullptr);
    pthread_join(t2,nullptr);
    pthread_join(t3,nullptr);
    return 0;
}